﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
#include<utility>
#include<string>
#include<functional>
#include<map>


using namespace std;

////统一的列表初始化
//struct Date
//{
//	int year;
//	int month;
//	int day;
//};
//
//void test1()
//{
//	Date d1{ 2024,11,14 };
//	const Date& d2{ 2024,11,14 };
//	int array1[]{ 1, 2, 3, 4, 5 };
//	int array2[5]{ 0 };
//
//
//	auto e = "str";
//
//
//}
//
////右值引用
//void test2()
//{
//	// 以下的p、b、c、*p都是左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = 2;
//	// 以下几个是对上面左值的左值引用
//	int*& rp = p;
//	int& rb = b;
//	const int& rc = c;
//	int& pvalue = *p;
//
//	//double x = 1.1, y = 2.2;
//	//// 以下几个都是常见的右值
//	//10;
//	//x + y;
//	//fmin(x, y);
//	//// 以下几个都是对右值的右值引用
//	//int&& rr1 = 10;
//	//double&& rr2 = x + y;
//	//double&& rr3 = fmin(x, y);
//	//// 这里编译会报错：error C2106: “=”: 左操作数必须为左值/表达式必须是可修改的左值
//	//10 = 1;
//	//x + y = 1;
//	//fmin(x, y) = 1;
//
//	//// 左值引用只能引用左值，不能引用右值。
//	//int a = 10;
//	//int& ra1 = a;   // ra为a的别名
//	////int& ra2 = 10;   // 编译失败，因为10是右值
//	//// const左值引用既可引用左值，也可引用右值。
//	//const int& ra3 = 10;
//	//const int& ra4 = a;
//	//// 右值引用只能右值，不能引用左值。
//	//int&& r1 = 10;
//
//	//// error C2440: “初始化”: 无法从“int”转换为“int &&”
//	//// message : 无法将右值引用绑定到左值
//	//int a = 10;
//	//int&& r2 = a;
//
//	//// 右值引用可以引用move以后的左值
//	//int&& r3 = std::move(a);
//	////move的实质相当于
//	//int&& rrx5 = (int&&)a;
//	
//	
//	//r1的属性为左值	
//	string&& r1 = string("2222");
//}
//
//template<class T>	//引用折叠
//void Func(T&& x)	//传左值即为左值引用，传右值即为右值引用
//{
//
//}



////解析方式1
////编译时递归推导解析参数
//void Print()
//{
//
//}
//template<class T,class ...Args>
//void Print(T&& x, Args&& ...args)
//{
//	cout << x << ' ';
//	//参数包参数数量为零时会调用无参的重载函数
//	Print(args...);
//}
//template<class ...Arg>
//void showList(Args&& ...args)
//{
//	Print(args...);
//}
//
//
//
//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//template<typename T>
//void PerfectForward(T&& t)
//{
//	//模板实例化左值引用,保持属性直接传参给Fun
//	//模板实例化右值引用，右值引用属性会退化成左值，转换成右值再传给Func
//
//	Fun(forward<T>(t));
//}
//
//
//
//
//namespace bit
//{
//	class string
//	{
//	public:
//		//移动构造
//		string(string&& s)
//			:str(nullptr)
//		{
//			//移动拷贝，抢夺资源
//			//所以右值引用即为标记
//			//s为右值引用，可能是将亡值，会直接将s的资源抢给自己
//			swap(s,*this);
//		}
//	private:
//		char* str;
//
//	};
//
//}





//int main()
//{
//	PerfectForward(int(1));
//	vector<int> v;
//	auto add1 = [](int x, int y)->int {return x + y};
//	sort(v.begin(), v.end(), [](const Good& g1, const Goods& g2)
//		{
//			return g1._price < g2._price;
//		});
//
//	return 0;
//}


//int main()
//{
//	int a = 1, b = 2;
//
//	//lambda只能用当前lambda局部域和捕捉的对象和全局对象
//	//传值捕捉本质是一种拷贝，并且const修饰了
//	auto swap2 = [a, b]()mutable//mutable慎用,mutable即——可修改的
//		{						//mutable相当于去掉const属性，可以修改了
//								//修改不会影响外面被捕捉的值，因为是一种拷贝
//			int tmp = a;
//			a = b;
//			b = tmp;
//		};
//
//	//引用捕捉，默认可修改
//	auto swap3 = [&a, &b]()
//		{
//
//		};
//
//}


int Plus(int a, int b)
{
	return a + b;
}
class Sub
{
public:
	
};

int sub(int a, int b)
	{
		return a - b;
	}
using placeholders::_1;
using placeholders::_2;
int main()
{
	//调整参数顺序
	auto sub1 = bind(sub, _1, _2);//_1代表第一个实参，_2代表第二个实参以此类推
	auto sub2 = bind(sub, _2, _1);
	cout << sub2(10, 5) << endl;

	//调整参数个数（常用）
	auto sub3 = bind(sub, 100, _1);//绑定死第一个形参
	cout << sub3(20) << endl;

}



//int main()
//{
//	//表示绑定函数plus 参数分别由调用 func1 的第一，二个参数指定
//	std::function<int(int, int)> func1 = std::bind(Plus, placeholders::_1,
//		placeholders::_2);
//	//auto func1 = std::bind(Plus, placeholders::_1, placeholders::_2);
//	//func2的类型为 function<void(int, int, int)> 与func1类型一样
//	//表示绑定函数 plus 的第一，二为： 1， 2
//	auto func2 = std::bind(Plus, _1, _2);
//	cout << func1(1, 2) << endl;
//	cout << func2() << endl;
//	Sub s;
//	// 绑定成员函数
//	std::function<int(int, int)> func3 = std::bind(&Sub::sub, s,
//		placeholders::_1, placeholders::_2);
//	// 参数调换顺序
//	std::function<int(int, int)> func4 = std::bind(&Sub::sub, s,
//		placeholders::_2, placeholders::_1);
//	cout << func3(1, 2) << endl;
//	cout << func4(1, 2) << endl;
//	return 0;
//}


//// 使用方法如下：
//
//int f(int a, int b)
//{
//	return a + b;
//}
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};
//class Plus
//{
//public:
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//	double plusd(double a, double b)
//	{
//		return a + b;
//	}
//};
//
//int main()
//{
//	// 函数名(函数指针)
//	std::function<int(int, int)> func1 = f;
//	cout << func1(1, 2) << endl;
//	// 函数对象
//	std::function<int(int, int)> func2 = Functor();
//	cout << func2(1, 2) << endl;
//	// lamber表达式
//	std::function<int(int, int)> func3 = [](const int a, const int b)
//		{return a + b; };
//	cout << func3(1, 2) << endl;
//
//	// 包装静态成员函数
//	std::function<int(int, int)> func4 = &Plus::plusi;
//	cout << func4(1, 2) << endl;
//	//包装普通成员函数，因为普通成员函数隐患this指针，（第一个参数传对象或指针）
//	//因为底层无论是对象或指针都是通过对象调成员函数
//	std::function<double(Plus*, double, double)> func5 = &Plus::plusd;
//	cout << func5(&Plus(), 1.1, 2.2) << endl;
//	std::function<double(Plus, double, double)> func6 = &Plus::plusd;
//	cout << func6(Plus(), 1.1, 2.2) << endl;
//	return 0;
//}
//
//
//int main1()
//{
//	//用operator[]进行访问
//	map < string, function<int(int, int)>> opFuncMap;
//}
